package com.huatai.bi.easyExcelListener;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.exception.ExcelAnalysisException;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.huatai.bi.utils.DateUtil;
import com.huatai.bi.utils.StringBuildUtil;
import com.huatai.bi.vo.excelVo.HeardVO;
import com.huatai.common.error.exception.ServiceException;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;

import java.util.*;

/**
 * @BelongsProject: itc-airport-cloud
 * @BelongsPackage: com.itc.bi.easyExcelListener
 * @Author: hecaiy
 * @CreateTime: 2024-09-17  18:18
 * @Description: TODO
 * @Version: 1.0
 */
@Data
public class LimitExcelReadListener extends AnalysisEventListener<LinkedHashMap<Integer, String>> {
    // 定义变量，分别表示限制列数和行数
    private Integer limitRowSize;
    // 定义变量，存储表头信息和表数据
    private List<HeardVO> heardVos = new ArrayList<>();
    private List<Map<String,Object>> bodyVos = new ArrayList<>();
    private Map<Integer, String> headMap = new HashMap<>();
    private Boolean isFirstRow = true;

    // 构造函数
    public LimitExcelReadListener() {

    }

    // 带参构造函数，直接赋值限制行列
    public LimitExcelReadListener( Integer limitRowSize) {
        this.limitRowSize = limitRowSize;
    }

    @Override
    public void invoke(LinkedHashMap<Integer, String> integerStringMap, AnalysisContext context) {
        // 获取限制列之后的Map，并存入dataList
        Map<String,Object> linkedHashMap = new LinkedHashMap<>();
        integerStringMap.forEach((key,value)->{
            String titleKey = headMap.get(key);
            linkedHashMap.put(titleKey,value);
            //判断是不是读取第一行数据
            if(isFirstRow){
                for (Map.Entry<Integer,String> entry:headMap.entrySet()){
                    if(key.equals(entry.getKey())){
                        //默认是字符串
                        String ColumnNameType = "string";
                        ReadCellData cell = (ReadCellData)context.readRowHolder().getCellMap().get(key);
                        if(cell!=null){
                            CellDataTypeEnum type = cell.getType();
                            //这里注意 虽然是日期 但是 类型 存储的是number 因为excel 存储的就是number
                            if(type.equals(CellDataTypeEnum.NUMBER)){
                                //特殊处理 时间格式的列 尝试转换为时间格式   若能转 则表示是时间格式
                                String format = cell.getDataFormatData().getFormat();
                                ColumnNameType = "number";
                                //日期类型处理
                                if(format.contains("yyyy") ||format.contains("yyyy-mm-dd") || format.contains("yyyy-m-d") || format.contains("yyyy-m-d h:mm:s")){
                                    if(DateUtil.toDate(value)){
                                        ColumnNameType = "date";
                                    }else {
                                        ColumnNameType = "string";
                                    }
                                }
                            }
                        }
                        heardVos.add(new HeardVO(titleKey,titleKey,ColumnNameType));
                    }
                }
            }
        });
        isFirstRow = false;
        bodyVos.add(linkedHashMap);
        // 判断行数已达到限制行数，抛出ExcelAnalysisException
        if (bodyVos.size() >= this.limitRowSize) {
            throw new ExcelAnalysisException("数据行读取完成");
        }
    }

    @Override
    public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
        Map<Integer, String> integerStringLinkedHashMap = new LinkedHashMap<>();
        // 获取限制列之后的表头Map，并存入headList
        for (Map.Entry<Integer, String> entry : headMap.entrySet()){
            String value = entry.getValue();
            if(StringUtils.isEmpty(value)){
                throw new ServiceException("列名不能为空");
            }
            StringBuildUtil.originalFilenameTS(value);
            integerStringLinkedHashMap.put(entry.getKey(),value.trim());
        }
        this.headMap = integerStringLinkedHashMap;
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
    }
}
